package com.qf.rbac2202.shiro;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.qf.rbac2202.sys.entity.SysMenu;
import com.qf.rbac2202.sys.entity.SysUser;
import com.qf.rbac2202.sys.service.ISysMenuService;
import com.qf.rbac2202.sys.service.ISysUserService;
import com.qf.rbac2202.utils.ApplicationContextUtils;
import com.qf.rbac2202.utils.Constants;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class CustomRealm extends AuthorizingRealm {

    @Autowired
    ISysUserService userService;

    @Autowired
    ISysMenuService menuService;


    /**
     * 获取角色和权限信息
     * @param principals
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        SysUser user = (SysUser)principals.getPrimaryPrincipal();
        Long userId = user.getUserId();
        SimpleAuthorizationInfo simpleAuthorizationInfo=new SimpleAuthorizationInfo( );
        //判断当前用户的id是否符合最高权限
        if(userId.longValue() == Constants.SUPER_ADMIN.longValue()){
            QueryWrapper< SysMenu > perms=new QueryWrapper< SysMenu >( );
            perms.select( "perms" );
            //查询一列
            List< Object > objects=menuService.listObjs( perms );
            //用流来处理这些数据,这段代码最为核心
            List< String > collect=objects.stream( )
                    .map( s->s.toString( ) )
                    .filter( s->s!=null&&!s.equals( "" ) )
                    .flatMap( s-> Arrays.stream( s.split( "," ) ))
                    .distinct( )
                    .collect( Collectors.toList() );
            simpleAuthorizationInfo.addStringPermissions( collect );
            return simpleAuthorizationInfo;

        }else {
            //调用方法获取属于对象的菜单
            List< SysMenu > belongUserMenuList=menuService.getBelongUserMenuList( userId );

            //转流
            List< String > collect=belongUserMenuList.stream( ).map( s->s.getPerms( ) ).collect( Collectors.toList( ) );

            //用流来处理这些数据,这段代码最为核心
            List< String > perList=collect.stream( )
                    .filter( s->s==null || s.equals( "" ) )
                    .map( s->s.toString( ) )
                    .flatMap( s->Arrays.stream( s.split( "," ) ) )
                    .distinct( )
                    .collect( Collectors.toList( ) );
            simpleAuthorizationInfo.addStringPermissions( perList );

            return simpleAuthorizationInfo;

        }


    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String) authenticationToken.getPrincipal();

        //查询用户信息
        SysUser user = userService.getOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUsername,username));

        //账号不存在
        if(user == null) {
            throw new UnknownAccountException("账号或密码不正确");
        }

        //账号锁定
        if(user.getStatus() == 0){
            throw new LockedAccountException("账号已被锁定,请联系管理员");
        }

        SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
        return info;
    }
}
